package com.smallrig.extension.ext;

import com.smallrig.extension.chain.Command;
import com.smallrig.extension.dto.BizSceneWrapper;
import com.smallrig.extension.ExtensionException;
import com.smallrig.extension.ExtensionSpi;
import com.smallrig.extension.anno.Extension;
import com.smallrig.extension.dto.BizScene;
import com.smallrig.extension.dto.BizScenes;
import com.smallrig.extension.utils.SpiUtils;
import org.springframework.aop.support.AopUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;

import javax.annotation.Resource;

public class ExtensionRegister {

    /**
     * 扩展点不合法
     */
    private static final String EXTENSION_ILLEGAL = "extension_illegal";

    @Resource
    private ExtensionRepository extensionRepository;


    public void doRegistration(ExtensionSpi extensionObject) {
        Class<?> extensionClz = extensionObject.getClass();
        if (AopUtils.isAopProxy(extensionObject)) {
            extensionClz = ClassUtils.getUserClass(extensionObject);
        }

        //能找到cglib代理的，不能找到jdk代理的，为毛？
        Extension extensionAnn = AnnotationUtils.findAnnotation(extensionClz, Extension.class);
        BizScenes bizScenes = bizScenes(extensionAnn,extensionObject);

        Class intf = getExtension(extensionClz);
        for (BizScene bizScene : bizScenes.getBizSceneList()) {
            BizSceneWrapper bizSceneWrapper = new BizSceneWrapper(intf.getName(), bizScene.getUniqueIdentity());
            extensionRepository.put(intf.getName(),bizSceneWrapper,extensionObject);
        }
    }

    private BizScenes bizScenes(Extension extensionAnn,ExtensionSpi extensionObject){
        BizScenes bizScenes = BizScenes.empty();

        if(null!=extensionAnn){
            BizScene bizScene = BizScene.valueOf(extensionAnn.bizId(), extensionAnn.version());
            bizScenes.add(bizScene);
        }
        BizScenes bizScenes2 = extensionObject.bizScenes();
        if(null!=bizScenes2){
            bizScenes.addAll(bizScenes2);
        }

        BizScene bizScene = extensionObject.bizScene();
        if(null!=bizScene){
            bizScenes.add(bizScene);
        }
        return bizScenes;
    }

    /**
     * @param targetClz
     * @return
     */
    private Class getExtension(Class<?> targetClz) {
        Class<?>[] interfaces = ClassUtils.getAllInterfacesForClass(targetClz);
        if (interfaces == null || interfaces.length == 0) {
            throw new ExtensionException(EXTENSION_ILLEGAL, "Please assign a extension point interface for " + targetClz);
        }

        for (Class intf : interfaces) {
            if(SpiUtils.asFrom(intf,ExtensionSpi.class)){
                return intf;
            }
        }

        String errMessage = "Your name of ExtensionPoint for " + targetClz + " must extends ExtensionSpi" ;
        throw new ExtensionException(EXTENSION_ILLEGAL, errMessage);
    }




}
